package chen.web.util.ubb;

/**
 * 非线程安全
 * @author chen
 *
 */
public class UbbParser {

	private EventHandler handler;
	private RootTag root;
	
	public UbbParser(EventHandler handler){
		this.handler = handler;
	}
	
	public RootTag parse(String ubb){
		root = new RootTag();
		StringBuilder sb = new StringBuilder();
		for(int i=0; i<ubb.length(); i++){
			char ch = ubb.charAt(i);
			if(ch == '['){
				int bi = i+1;
				if(bi<ubb.length()){
					if(ubb.charAt(bi) == '/'){
						i = scanEndTag(ubb, bi+1, sb);
					} else {
						i = scanStartTag(ubb, bi, sb);
					}
				} else {
					sb.append(ch);
				}
			} else {
				sb.append(ch);
			}
		}
		
		if(sb.length() > 0){
			fireEvent(new FindTextEvent(root, sb.toString()));
		}
		root.close();
		return root;
	}
	
	//结束标签最大往前寻找的字符数
	private int maxScanCount4EndTag = UbbTag.NameMaxLength + 1;	
	/**
	 * 寻找结束标签，返回扫寻找的位置
	 * @param ubb
	 * @param i
	 * @param sb
	 * @return
	 */
	private int scanEndTag(String ubb, int i, StringBuilder sb){
		int n=0;
		for(int j=i; j<ubb.length() && n<maxScanCount4EndTag; j++,n++){
			char ch = ubb.charAt(j);
			if(ch == ']'){
				String tagName = ubb.substring(i, j);
				if(sb.length() > 0){
					fireEvent(new FindTextEvent(root, sb.toString()));;
					sb.setLength(0);
				}
				fireEvent(new FindEndTagNameEvent(root, tagName));
				return j;
			}
		}
		
		//扫描结束//
		
		int index = 0;	//定义当前扫描到的位置
		if(n == maxScanCount4EndTag){	//达到最大寻找数量限制而结束的
			index = i+maxScanCount4EndTag-1;
		} else {	//字符串解析结束
			index = ubb.length()-1;
		}
		sb.append(ubb.substring(i-2, index+1));
		return index;
	}
	
	
	//开始标签最大往前寻找的字符数
	private int maxScanCount4StartTag = UbbTag.NameMaxLength + 2;
	/**
	 * 寻找开始标签，返回扫寻找的位置
	 * @param ubb
	 * @param i
	 * @param sb
	 * @return
	 */
	private int scanStartTag(String ubb, int i, StringBuilder sb){
		int n=0;
		for(int j=i; j<ubb.length() && n<maxScanCount4StartTag; j++,n++){
			char ch = ubb.charAt(j);
			if(ch == ']'){
				if(sb.length() > 0){	//清空之前的内容
					fireEvent(new FindTextEvent(root, sb.toString()));
					sb.setLength(0);
				}
				if(ubb.charAt(j-1) == '/'){	//闭合标签形式
					String tagName = ubb.substring(i, j-1);	
					fireEvent(new FindStartTagEvent(root, tagName, null));
					fireEvent(new FindEndTagNameEvent(root, tagName));
				} else {//非闭合标签形式
					String tagName = ubb.substring(i, j);
					fireEvent(new FindStartTagEvent(root, tagName, null));
				}
				return j;
			}else if(ch == '='){
				String tagName = ubb.substring(i, j);
				for(int k=j+1; k<ubb.length(); k++){		//寻找property
					char ck = ubb.charAt(k);
					if(ck == ']'){		//找到property
						if(sb.length() > 0){ //清空之前的内容
							fireEvent(new FindTextEvent(root, sb.toString()));
							sb.setLength(0);
						}
						if(ubb.charAt(k-1) == '/'){	//闭合标签形式
							String property = ubb.substring(j+1, k-1);	
							fireEvent(new FindStartTagEvent(root, tagName, property));
							fireEvent(new FindEndTagNameEvent(root, tagName));
						} else {
							String property = ubb.substring(j+1, k);
							fireEvent(new FindStartTagEvent(root, tagName, property));
						}
						return k;
					}else if(ck == '['){		//寻找property失败
						sb.append(ubb.substring(i-1, k));
						return k-1;
					}
				}
				sb.append(ubb.substring(i-1));
				return ubb.length() - 1;
			}else if(ch == '['){
				sb.append(ubb.substring(i-1, j));
				return j-1;
			}
		}
		//扫描结束//
		
		int index = 0;	//定义当前扫描到的位置
		if(n == maxScanCount4StartTag){	//达到最大寻找数量限制而结束的
			index = i+maxScanCount4StartTag-1;
		} else {	//字符串解析完毕结束
			index = ubb.length()-1;
		}
		sb.append(ubb.substring(i-1, index+1));
		return index;
	}
	
	private void fireEvent(Event event){
		handler.handler(event);
	}
}
